# -*- coding:utf-8 -*-

from typing import List
from datetime import datetime, time
from module_admin.entity.do.role_do import SysRoleDept
from sqlalchemy import and_, delete, desc, func, or_, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from module_gen.constants.gen_constants import GenConstants
from module_doc.entity.do.bg_file_category_do import BgFileCategory
from module_doc.entity.vo.bg_file_category_vo import BgFileCategoryPageModel, BgFileCategoryModel, \
    BgFileCategoryAddModel
from utils.page_util import PageUtil, PageResponseModel
from utils.common_util import CamelCaseUtil


class BgFileCategoryDao:

    @classmethod
    async def get_by_id(cls, db: AsyncSession, bg_file_category_id: int) -> BgFileCategory:
        """根据主键获取单条记录"""
        bg_file_category = (((await db.execute(
                            select(BgFileCategory)
                            .where(BgFileCategory.id == bg_file_category_id)))
                       .scalars())
                       .first())
        return bg_file_category

    @classmethod
    async def get_by_info(cls, db: AsyncSession, query_object: BgFileCategoryPageModel) -> BgFileCategory:
        """根据主键获取单条记录"""
        bg_file_category = (((await db.execute(
                            select(BgFileCategory)
                            .where(BgFileCategory.category_name == query_object.category_name if query_object.category_name else True,
                                   BgFileCategory.parent_id == query_object.parent_id if query_object.parent_id else True)))
                       .scalars())
                       .first())
        return bg_file_category

    """
    查询
    """
    @classmethod
    async def get_bg_file_category_list(cls, db: AsyncSession,
                             query_object: BgFileCategoryPageModel,
                             data_scope_sql: str = None,
                             is_page: bool = False) -> [list | PageResponseModel]:

        query = (
            select(BgFileCategory)
            .where(
                BgFileCategory.ancestors == query_object.ancestors if query_object.ancestors else True,
                BgFileCategory.category_name.like(f"%{query_object.category_name}%") if query_object.category_name else True,
                BgFileCategory.parent_id == query_object.parent_id if query_object.parent_id is not None else True,
                BgFileCategory.status == query_object.status if query_object.status else True,
                BgFileCategory.del_flag == '0',
                eval(data_scope_sql) if data_scope_sql else True,
            )
            .order_by(desc(BgFileCategory.create_time))
            .distinct()
        )
        bg_file_category_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
        return bg_file_category_list


    @classmethod
    async def add_bg_file_category(cls, db: AsyncSession, add_model: BgFileCategoryAddModel, auto_commit: bool = True) -> BgFileCategoryModel:
        """
        增加
        """
        bg_file_category =  BgFileCategory(**add_model.model_dump(exclude_unset=True, ))
        db.add(bg_file_category)
        await db.flush()
        bg_file_category_model = BgFileCategoryModel(**CamelCaseUtil.transform_result(bg_file_category))
        if auto_commit:
            await db.commit()
        return bg_file_category_model

    @classmethod
    async def edit_bg_file_category(cls, db: AsyncSession, edit_model: BgFileCategoryModel, auto_commit: bool = True) -> BgFileCategory:
        """
        修改
        """
        edit_dict_data = edit_model.model_dump(exclude_unset=True, exclude={ *GenConstants.DAO_COLUMN_NOT_EDIT })
        await db.execute(update(BgFileCategory), [edit_dict_data])
        await db.flush()
        if auto_commit:
            await db.commit()
        return await cls.get_by_id(db, edit_model.id)

    @classmethod
    async def del_bg_file_category(cls, db: AsyncSession, bg_file_category_ids: List[str], soft_del: bool = True, auto_commit: bool = True):
        """
        删除
        """
        if soft_del:
            await db.execute(update(BgFileCategory).where(BgFileCategory.id.in_(bg_file_category_ids)).values(del_flag='2'))
        else:
            await db.execute(delete(BgFileCategory).where(BgFileCategory.id.in_(bg_file_category_ids)))
        await db.flush()
        if auto_commit:
            await db.commit()

    @classmethod
    async def get_bg_file_category_tree(cls, db: AsyncSession, query_object: BgFileCategoryPageModel = None) -> List[dict]:
        """
        获取文件分类树形结构
        """
        if query_object is None:
            query_object = BgFileCategoryPageModel()
            
        query = (
            select(BgFileCategory)
            .where(
                BgFileCategory.status == query_object.status if query_object.status else True,
                BgFileCategory.del_flag == '0'
            )
            .order_by(BgFileCategory.order_num, BgFileCategory.create_time)
        )
        
        result = await db.execute(query)
        categories = result.scalars().all()
        
        # 转换为字典列表
        category_list = []
        for category in categories:
            category_dict = CamelCaseUtil.transform_result(category)
            category_list.append(category_dict)
        
        # 构建树形结构
        return cls._build_tree(category_list, None)

    @classmethod
    async def get_bg_file_category_children(cls, db: AsyncSession, parent_id: int) -> List[dict]:
        """
        获取指定父分类下的子分类列表
        """
        query = (
            select(BgFileCategory)
            .where(
                BgFileCategory.parent_id == parent_id,
                BgFileCategory.del_flag == '0'
            )
            .order_by(BgFileCategory.order_num, BgFileCategory.create_time)
        )
        
        result = await db.execute(query)
        categories = result.scalars().all()
        
        # 转换为字典列表
        children_list = []
        for category in categories:
            category_dict = CamelCaseUtil.transform_result(category)
            children_list.append(category_dict)
        
        return children_list

    @classmethod
    def _build_tree(cls, category_list: List[dict], parent_id: int = None) -> List[dict]:
        """
        构建树形结构
        """
        tree = []
        for category in category_list:
            # 处理顶级分类（parent_id为null或0）和子分类
            category_parent_id = category.get('parentId')
            if (parent_id is None and (category_parent_id is None or category_parent_id == 0)) or \
               (parent_id is not None and category_parent_id == parent_id):
                children = cls._build_tree(category_list, category.get('id'))
                if children:
                    category['children'] = children
                tree.append(category)
        return tree